home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 23 / AMIGAplus Sonderheft 23 (2000)(Falke)(DE)[!].iso / Updates / Datatypes / PCD-DT / Source / dispatcher.c next >
C/C++ Source or Header  |  1999-11-14  |  9KB  |  375 lines

  1. #include <clib/alib_protos.h>
  2. #include <pragma/datatypes_lib.h>
  3. #include <pragma/dos_lib.h>
  4. #include <pragma/exec_lib.h>
  5. #include <pragma/intuition_lib.h>
  6. #include <pragma/graphics_lib.h>
  7. #include <pragma/render_lib.h>
  8. #include <pragma/utility_lib.h>
  9. #include <cybergraphx/cybergraphics.h>
  10. #include <datatypes/pictureclass.h>
  11. #include <dos/dostags.h>
  12. #include <exec/memory.h>
  13. #include <intuition/icclass.h>
  14. #include <stdio.h>
  15. #include <string.h>
  16.  
  17. struct Arg1
  18. {
  19. long *mode,*res,*dither,*depth;
  20. };
  21.  
  22. struct Arg2
  23. {
  24. long mode,res,dither,depth;
  25. };
  26.  
  27. extern Library *SuperClassBase,*RenderBase;
  28.  
  29. static void ReadPrefs(Arg2 *arg)
  30. {
  31. char *var;
  32. arg->mode=1;
  33. arg->res=2;
  34. arg->dither=0;
  35. arg->depth=8;
  36. if(var=(char *)AllocVec(256,0))
  37.     {
  38.     if(GetVar("ENV:DataTypes/pcd.prefs",var,256,LV_VAR|GVF_GLOBAL_ONLY)>=0)
  39.         {
  40.         RDArgs *rdargs;
  41.       if(rdargs=(RDArgs *)AllocDosObject(DOS_RDARGS,0))
  42.             {
  43.             RDArgs *args;
  44.             Arg1 para={0,0,0,0};
  45.             rdargs->RDA_Source.CS_Buffer=var;
  46.             rdargs->RDA_Source.CS_Length=strlen(var);
  47.             rdargs->RDA_Source.CS_CurChr=0;
  48.             if(args=ReadArgs("MODE/A/N,RESOLUTION/A/N,DITHER/A/N,DEPTH/A/N",(long *)¶,rdargs))
  49.                 {
  50.                 if(para.mode)
  51.                     {
  52.                     arg->mode=*para.mode;
  53.                     if(arg->mode<0) arg->mode=0;
  54.                     else if(arg->mode>1) arg->mode=1;
  55.                     }
  56.                 if(para.res)
  57.                     {
  58.                     arg->res=*para.res;
  59.                     if(arg->res<0) arg->res=0;
  60.                     else if(arg->res>5) arg->res=5;
  61.                     }
  62.                 if(para.dither)
  63.                     {
  64.                     arg->dither=*para.dither;
  65.                     if(arg->dither<0) arg->dither=0;
  66.                     else if(arg->dither>1) arg->dither=1;
  67.                     }
  68.                 if(para.depth)
  69.                     {
  70.                     arg->depth=*para.depth;
  71.                     if(arg->depth<3) arg->depth=3;
  72.                     else if(arg->depth>8) arg->depth=8;
  73.                     }
  74.                 FreeArgs(args);
  75.                 }
  76.             FreeDosObject(DOS_RDARGS,rdargs);
  77.             }
  78.         }
  79.     FreeVec(var);
  80.     }
  81. if(SuperClassBase->lib_Version!=43) arg->mode=0;
  82. }
  83.  
  84. ULONG Colors2DT(Object *obj,UBYTE *color)
  85. {
  86. UBYTE *cr;
  87. ULONG *cregs,i,num,error=0;
  88. GetDTAttrs(obj,PDTA_NumColors,&num,PDTA_ColorRegisters,&cr,PDTA_CRegs,&cregs,TAG_END);
  89. if(cr&&cregs)
  90.     {
  91.     for(i=0;i<num;i++,cr+=3,cregs+=3,color+=4)
  92.         {
  93.         cr[0]=color[1];
  94.         cr[1]=color[2];
  95.         cr[2]=color[3];
  96.         cregs[0]=cr[0]<<24;
  97.         cregs[1]=cr[1]<<24;
  98.         cregs[2]=cr[2]<<24;
  99.         }
  100.     }
  101. else error=ERROR_NO_FREE_STORE;
  102. return error;
  103. }
  104.  
  105. static ULONG ReadP6(Object *obj,BitMapHeader *bh,BitMap *bm,BPTR file,Arg2 *arg)
  106. {
  107. ULONG error=0;
  108. UBYTE *rgb;
  109. if(rgb=(UBYTE *)AllocVec(bh->bmh_Width*bh->bmh_Height*4,MEMF_CLEAR))
  110.     {
  111.     UBYTE *buffer;
  112.     if(buffer=(UBYTE *)AllocVec(bh->bmh_Width*3,0))
  113.         {
  114.         UWORD y;
  115.         UBYTE *p1=rgb;
  116.         for(y=0;y<bh->bmh_Height;y++)
  117.             {
  118.             UWORD x;
  119.             UBYTE *p2=buffer;
  120.             if(Read(file,buffer,bh->bmh_Width*3)!=bh->bmh_Width*3)
  121.                 {
  122.                 error=DTERROR_NOT_ENOUGH_DATA;
  123.                 break;
  124.                 }
  125.             for(x=0;x<bh->bmh_Width;x++,p1+=4,p2+=3)
  126.                 {
  127.                 p1[1]=p2[0];
  128.                 p1[2]=p2[1];
  129.                 p1[3]=p2[2];
  130.                 }
  131.             }
  132.         FreeVec(buffer);
  133.         if(!error)
  134.             {
  135.             APTR rmh;
  136.             if(rmh=CreateRMHandler(RND_MemType,RMHTYPE_POOL,TAG_END))
  137.                 {
  138.                 ULONG *palette;
  139.                 if(palette=CreatePalette(RND_RMHandler,rmh,TAG_END))
  140.                     {
  141.                     APTR hst;
  142.                     if(hst=CreateHistogram(RND_RMHandler,rmh,TAG_END))
  143.                         {
  144.                         if(AddRGBImage(hst,(ULONG *)rgb,bh->bmh_Width,bh->bmh_Height,TAG_END)==ADDH_SUCCESS)
  145.                             {
  146.                             if(ExtractPalette(hst,palette,1<<bh->bmh_Depth,TAG_END)==EXTP_SUCCESS)
  147.                                 {
  148.                                 UBYTE *chunky;
  149.                                 if(chunky=(UBYTE *)AllocVec(bh->bmh_Width*bh->bmh_Height,0))
  150.                                     {
  151.                                     if(Render((ULONG *)rgb,bh->bmh_Width,bh->bmh_Height,chunky,palette,RND_DitherMode,arg->dither,TAG_END)==REND_SUCCESS)
  152.                                         {
  153.                                         UBYTE *color;
  154.                                         if(color=(UBYTE *)AllocVec((1<<bh->bmh_Depth)*4,0))
  155.                                             {
  156.                                             ExportPalette(palette,color,TAG_END);
  157.                                             if(!(error=Colors2DT(obj,color))) Chunky2BitMap(chunky,0,0,bh->bmh_Width,bh->bmh_Height,bm,0,0,TAG_END);
  158.                                             FreeVec(color);
  159.                                             }
  160.                                         else error=ERROR_NO_FREE_STORE;
  161.                                         }
  162.                                     else error=ERROR_NO_FREE_STORE;
  163.                                     FreeVec(chunky);
  164.                                     }
  165.                                 else error=ERROR_NO_FREE_STORE;
  166.                                 }
  167.                             else error=ERROR_NO_FREE_STORE;
  168.                             }
  169.                         else error=ERROR_NO_FREE_STORE;
  170.                         DeleteHistogram(hst);
  171.                         }
  172.                     else error=ERROR_NO_FREE_STORE;
  173.                     DeletePalette(palette);
  174.                     }
  175.                 else error=ERROR_NO_FREE_STORE;
  176.                 DeleteRMHandler(rmh);
  177.                 }
  178.             else error=ERROR_NO_FREE_STORE;
  179.             }
  180.         }
  181.     else error=ERROR_NO_FREE_STORE;
  182.     FreeVec(rgb);
  183.     }
  184. else error=ERROR_NO_FREE_STORE;
  185. return error;
  186. }
  187.  
  188. static ULONG ReadP6_V43(Object *obj,BitMapHeader *bh,BPTR file)
  189. {
  190. ULONG error=0,len=bh->bmh_Width*bh->bmh_Height*3;
  191. UBYTE *pix;
  192. if(pix=(UBYTE *)AllocVec(len,0))
  193.     {
  194.     if(Read(file,pix,len)==len) DoMethod(obj,PDTM_WRITEPIXELARRAY,pix,RECTFMT_RGB,bh->bmh_Width*3,0,0,bh->bmh_Width,bh->bmh_Height);
  195.     else error=DTERROR_NOT_ENOUGH_DATA;
  196.     FreeVec(pix);
  197.     }
  198. else if(pix=(UBYTE *)AllocVec(bh->bmh_Width*3,0))
  199.     {
  200.     UWORD y;
  201.     for(y=0;y<bh->bmh_Height;y++)
  202.         {
  203.         if(Read(file,pix,bh->bmh_Width*3)!=bh->bmh_Width*3)
  204.             {
  205.             error=DTERROR_NOT_ENOUGH_DATA;
  206.             break;
  207.             }
  208.         DoMethod(obj,PDTM_WRITEPIXELARRAY,pix,RECTFMT_RGB,bh->bmh_Width*3,0,y,bh->bmh_Width,1);
  209.         }
  210.     FreeVec(pix);
  211.     }
  212. else error=ERROR_NO_FREE_STORE;
  213. return error;
  214. }
  215.  
  216. static ULONG ReadNum(BPTR file)
  217. {
  218. ULONG retval=0;
  219. for(;;)
  220.     {
  221.     char c;
  222.     if(Read(file,&c,1)!=1) return 0;
  223.     if(c==10||c==32) break;
  224.     retval*=10;
  225.     retval+=c-'0';
  226.     }
  227. return retval;
  228. }
  229.  
  230. static ULONG GetPicture(IClass *cl,Object *obj)
  231. {
  232. ULONG error=0;
  233. BPTR nil;
  234. if(nil=Open("NIL:",MODE_OLDFILE))
  235.     {
  236.     char *fname,*dname,tmp[L_tmpnam];
  237.     Arg2 arg;
  238.     ReadPrefs(&arg);
  239.     GetDTAttrs(obj,DTA_Name,&dname,TAG_END);
  240.     if(dname)
  241.         {
  242.         SetDTAttrs(obj,0,0,DTA_ObjName,dname,TAG_END);
  243.         tmpnam(tmp);
  244.         strncpy(tmp,"PIPE:",5);
  245.         if(fname=(char *)AllocVec(strlen(dname)+L_tmpnam+50,0))
  246.             {
  247.             SPrintf(fname,"run pcdtoppm >%s -%lu -ppm \"%s%\"",tmp,arg.res+1,dname);
  248.             if(Execute(fname,nil,nil)!=DOSFALSE)
  249.                 {
  250.                 BPTR file;
  251.                 if(file=Open(tmp,MODE_OLDFILE))
  252.                     {
  253.                     BitMapHeader *bh;
  254.                     char head[3];
  255.                     GetDTAttrs(obj,PDTA_BitMapHeader,&bh,TAG_END);
  256.                     if(bh)
  257.                         {
  258.                         if(Read(file,head,3)==3)
  259.                             {
  260.                             bh->bmh_Width=ReadNum(file);
  261.                             bh->bmh_PageWidth=bh->bmh_Width;
  262.                             bh->bmh_Height=ReadNum(file);
  263.                             bh->bmh_PageHeight=bh->bmh_Height;
  264.                             bh->bmh_Compression=1;
  265.                             ReadNum(file);
  266.                             if(!arg.mode)
  267.                                 {
  268.                                 if(RenderBase)
  269.                                     {
  270.                                     BitMap *bm;
  271.                                     bh->bmh_Depth=arg.depth;
  272.                                     SetDTAttrs(obj,0,0,DTA_NominalHoriz,bh->bmh_Width,DTA_NominalVert,bh->bmh_Height,PDTA_NumColors,1<<arg.depth,TAG_END);
  273.                                     if(bm=AllocBitMap(bh->bmh_Width,bh->bmh_Height,bh->bmh_Depth,BMF_CLEAR|BMF_STANDARD|BMF_DISPLAYABLE,0))
  274.                                         {
  275.                                         SetDTAttrs(obj,0,0,PDTA_ModeID,BestModeID(BIDTAG_NominalWidth,bh->bmh_Width,BIDTAG_NominalHeight,bh->bmh_Height,BIDTAG_Depth,bh->bmh_Depth,TAG_END),PDTA_BitMap,bm,TAG_END);
  276.                                         error=ReadP6(obj,bh,bm,file,&arg);
  277.                                         }
  278.                                     else error=ERROR_NO_FREE_STORE;
  279.                                     }
  280.                                 else error=ERROR_NOT_IMPLEMENTED;
  281.                                 }
  282.                             else
  283.                                 {
  284.                                 bh->bmh_Depth=24;
  285.                                 SetDTAttrs(obj,0,0,DTA_ErrorNumber,&error,DTA_NominalHoriz,bh->bmh_Width,DTA_NominalVert,bh->bmh_Height,PDTA_ModeID,0,PDTA_SourceMode,PMODE_V43,TAG_END);
  286.                                 if(!error) error=ReadP6_V43(obj,bh,file);
  287.                                 }
  288.                             }
  289.                         else error=DTERROR_NOT_ENOUGH_DATA;
  290.                         }
  291.                     else error=ERROR_NO_FREE_STORE;
  292.                     Close(file);
  293.                     }
  294.                 else error=IoErr();
  295.                 }
  296.             else error=IoErr();
  297.             FreeVec(fname);
  298.             }
  299.         else error=ERROR_NO_FREE_STORE;
  300.         }
  301.     else error=ERROR_NO_FREE_STORE;
  302.     Close(nil);
  303.     }
  304. else error=IoErr();
  305. return error;
  306. }
  307.  
  308. static ULONG mNew(IClass *cl,Object *obj,opSet *msg)
  309. {
  310. TagItem *ti;
  311. if(ti=FindTagItem(DTA_SourceType,msg->ops_AttrList))
  312.     {
  313.     if(ti->ti_Data!=DTST_FILE&&ti->ti_Data!=DTST_CLIPBOARD&&ti->ti_Data!=DTST_RAM)
  314.         {
  315.         SetIoErr(ERROR_OBJECT_WRONG_TYPE);
  316.         return 0;
  317.         }
  318.     }
  319. if(obj==(Object *)cl)
  320.     {
  321.     if(obj=(Object *)DoSuperMethodA(cl,obj,Msg(msg)))
  322.         {
  323.         ULONG error;
  324.         if(error=GetPicture(cl,obj))
  325.             {
  326.             SetIoErr(error);
  327.             CoerceMethod(cl,obj,OM_DISPOSE);
  328.             obj=0;
  329.             }
  330.         }
  331.     }
  332. else
  333.     {
  334.     SetIoErr(ERROR_NOT_IMPLEMENTED);
  335.     obj=0;
  336.     }
  337. return ULONG(obj);
  338. }
  339.  
  340. static ULONG mSet(IClass *cl,Object *obj,opSet *msg)
  341. {
  342. ULONG retval;
  343. if(retval=DoSuperMethodA(cl,obj,Msg(